package org.example.day05;

/**
 * 第二章节2.2.9.1: synchronized修饰实例方法和修饰静态方法用到的锁是不同的.
 *      修饰静态方法是类锁，修饰实例方法是对象锁.
 */
public class MyThread5 {
    //静态
    //用到的锁是 MyThread5.class 对象
    synchronized public static void printA(){
        try {
            System.out.println("线程名称为: " + Thread.currentThread().getName() + " 进入printA的时间: " + System.currentTimeMillis());
            Thread.sleep(3000);
            System.out.println("线程名称为: " + Thread.currentThread().getName() + " 推出printA: " + System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    //静态
    //用到的锁是 MyThread5.class 对象
    synchronized public static void printB(){
        System.out.println("线程名称为: " + Thread.currentThread().getName() + " 进入printB的时间: " + System.currentTimeMillis());
        System.out.println("线程名称为: " + Thread.currentThread().getName() + " 推出printB: " + System.currentTimeMillis());
    }
    //实例
    //用到的锁是 m5 对象
    synchronized public void printC(){
        System.out.println("线程名称为: " + Thread.currentThread().getName() + " 进入printC的时间: " + System.currentTimeMillis());
        System.out.println("线程名称为: " + Thread.currentThread().getName() + " 推出printC: " + System.currentTimeMillis());
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread5 m5 = new MyThread5();
        Thread5A ta = new Thread5A(m5);
        ta.setName("A");
        ta.start();
        Thread.sleep(100);
        Thread5B tb = new Thread5B(m5);
        tb.setName("B");
        tb.start();
        Thread.sleep(100);
        Thread5C tc = new Thread5C(m5);
        tc.setName("C");
        tc.start();
    }
}

class Thread5A extends Thread{
    private MyThread5 m5;

    public Thread5A(MyThread5 m5) {
        this.m5 = m5;
    }

    @Override
    public void run() {
        m5.printA();
    }
}

class Thread5B extends Thread{
    private MyThread5 m5;

    public Thread5B(MyThread5 m5) {
        this.m5 = m5;
    }

    @Override
    public void run() {
        m5.printB();
    }
}

class Thread5C extends Thread{
    private MyThread5 m5;

    public Thread5C(MyThread5 m5) {
        this.m5 = m5;
    }

    @Override
    public void run() {
        m5.printC();
    }
}